
#include <sstream>
#include "BarEdition.h"

using namespace std;

void TW_CALL BarEdition::SetStart(void * baredit)
{
    BarEdition * bar =(BarEdition *)baredit;
    bar->skelAnim->start= bar->skelAnim->time;
}
void TW_CALL BarEdition::SetStop(void * baredit)
{
    BarEdition * bar =(BarEdition *)baredit;
    bar->skelAnim->stop= bar->skelAnim->time;

}

BarEdition::BarEdition(SkeletonAnim * skelAnim) : skelAnim(skelAnim)
{

}

void BarEdition::Create()
{
    TwCopyCDStringToClientFunc(CopyCDStringToClient);
    //TwCopyStdStringToClientFunc(CopyStdStringToClient);

    m_bar = TwNewBar("BVH Info");
    m_barConfig = TwNewBar("Edition");

    TwDefine(" GLOBAL help='Editing application of bvh.' "); // Message added to the help bar.

    TwAddVarRW(m_bar, "Rotation", TW_TYPE_QUAT4F, &skelAnim->quat, "");

    // Add 'speed' to 'bar': it is a modifable (RW) variable of type TW_TYPE_DOUBLE. Its key shortcuts are [s] and [S].
    TwAddVarRW(m_bar, "speed", TW_TYPE_DOUBLE, &skelAnim->speed,
               " label='Speed ratio' min=0.0 max=2.0 step=0.01 keyIncr=s keyDecr=S help='Movement speed (turns/second)' ");

    // Add 'time' to 'bar': it is a read-only (RO) variable of type TW_TYPE_DOUBLE, with 1 precision digit
    TwAddVarRW(m_bar, "time", TW_TYPE_DOUBLE, &skelAnim->time, " min=0.000 max=1 step=0.001 label='Time' precision=5 help='Time (in %).' ");

    { /////Liste BVH



    TwEnumVal * seasonsEV = new TwEnumVal[skelAnim->listbvh.size()];

    std::ostringstream filesenum;
    filesenum<<" enum='";
    int i;
    for(i=0; i<skelAnim->listbvh.size()-1;i++)
    {
        seasonsEV[i].Value=i;
        seasonsEV[i].Label=(skelAnim->listbvh[i]).c_str();
        filesenum<<i<<" {"<<skelAnim->listbvh[i]<<"},";
    }
    seasonsEV[i].Value=i;
    seasonsEV[i].Label=skelAnim->listbvh[i].c_str();
    filesenum<<i<<" {"<<skelAnim->listbvh[i]<<"}";
    filesenum<<"' ";
    TwType seasonType;

    seasonType = TwDefineEnum("Files", seasonsEV, skelAnim->listbvh.size());
    TwAddVarRW(m_bar, "Files", seasonType, &skelAnim->fileid, filesenum.str().c_str());

    std::ostringstream def;
    def<<" label='File id' min=0 max="<<skelAnim->listbvh.size()-1<<" step=1 help='The id in the bvh files name array.' ";

    TwAddVarRW(m_bar, "fileid", TW_TYPE_UINT16, &skelAnim->fileid,
               def.str().c_str());

    //////////////////Liste BVH///////////////////////////
    }
    TwAddVarRW(m_barConfig, "Running", TW_TYPE_BOOLCPP, &skelAnim->running, " key='SPACE' true=Running false=Stoped ");

    TwAddVarRW(m_barConfig, "start", TW_TYPE_DOUBLE, &skelAnim->start,
               " min=0.0 max=0.999 step=0.001 label='Start time' precision=5 help='Start of the animation (in %).' ");
    TwAddButton(m_barConfig, "Set start", SetStart, this, " label='Set start' ");

    TwAddVarRW(m_barConfig, "end", TW_TYPE_DOUBLE, &skelAnim->stop,
               " min=0.001 max=1 step=0.001 label='End time' precision=5 help='End of the animation (in %).' ");
    TwAddButton(m_barConfig, "Set end", SetStop, this, " label='Set end' ");

    {
        TwEnumVal * typedirEV = new TwEnumVal[3];
        int i;
       for(i=0; i<3;i++)
        {
            typedirEV[i].Value=i;
            typedirEV[i].Label=InfoChain::MovDirStr[i].c_str();
        }
        std::ostringstream typedirenum;
        typedirenum<<" enum='"<<0<<"{"<<InfoChain::MovDirStr[0]<<"},"<<1<<"{"<<InfoChain::MovDirStr[1]<<"},"<<2<<"{"<<InfoChain::MovDirStr[2]<<"}'";
        TwType typedirType;

        typedirType = TwDefineEnum("TypeDir", typedirEV, 3);
        TwAddVarRW(m_barConfig, "TypeDir", typedirType, &skelAnim->typeDir, typedirenum.str().c_str());
    }

    {
        TwEnumVal * movstateEV = new TwEnumVal[3];
        int i;
       for(i=0; i<3;i++)
        {
            movstateEV[i].Value=i;
            movstateEV[i].Label=InfoChain::MovStateStr[i].c_str();
        }
        std::ostringstream movstateenum;
        movstateenum<<" enum='"<<0<<"{"<<InfoChain::MovStateStr[0]<<"},"<<1<<"{"<<InfoChain::MovStateStr[1]<<"},"<<2<<"{"<<InfoChain::MovStateStr[2]<<"}'";
        TwType movstateType;

        movstateType = TwDefineEnum("MovState", movstateEV, 3);
        TwAddVarRW(m_barConfig, "MovState", movstateType, &skelAnim->movState, movstateenum.str().c_str());
    }

    TwAddVarRW(m_barConfig, "Filename", TW_TYPE_CDSTRING, &skelAnim->filename, "label='Ouput file'");

    TwAddButton(m_barConfig, "Save Bvh", SkeletonAnim::saveBvh, skelAnim, " label='Save bvh' ");

}


BarEdition::~BarEdition()
{
   // delete m_bar;
}


void TW_CALL BarEdition::CopyStdStringToClient(std::string& destinationClientString, const std::string& sourceLibraryString)
{
  // Copy the content of souceString handled by the AntTweakBar library to destinationClientString handled by your application
  destinationClientString = sourceLibraryString;
}

void TW_CALL BarEdition::CopyCDStringToClient(char **destPtr, const char *src)
{
  size_t srcLen = (src!=NULL) ? strlen(src) : 0;
  size_t destLen = (*destPtr!=NULL) ? strlen(*destPtr) : 0;

  // alloc or realloc dest memory block if needed
  if( *destPtr==NULL )
    *destPtr = (char *)malloc(srcLen+1);
  else if( srcLen>destLen )
    *destPtr = (char *)realloc(*destPtr, srcLen+1);

  // copy src
  if( srcLen>0 )
    strncpy(*destPtr, src, srcLen);
  (*destPtr)[srcLen] = '\0'; // null-terminated string
}
